package com.clt.web.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.clt.web.common.request.MsgTypes;
import com.clt.web.common.response.Article;
import com.clt.web.common.response.BaseMessage;
import com.clt.web.common.response.NewsMessage;
import com.clt.web.common.response.TextMessage;
import com.clt.web.pojo.WxAutoreply;
import com.clt.web.service.IWxAutoreplyService;
import com.clt.web.service.IWxCoreService;
import com.clt.web.utils.ParseXmlUtil;

/**
 * 处理微信请求的核心类
 * 
 * @author wenjian
 * 
 */
@Service
public class WxCoreServiceImpl implements IWxCoreService {

	private final Logger log = LoggerFactory.getLogger(getClass());
	private String basePath;// 查看详情时用的网站网址
	@Autowired
	private IWxAutoreplyService wxAutoreplyService;

	/**
	 * 处理微信基本请求
	 */
	public String processRequest(HttpServletRequest request) {
		basePath = request.getScheme() + "://" + request.getServerName()
				+ ":" +request.getServerPort()+ request.getContextPath();
		try {
			// xml请求解析,requestMap中包含:发送方帐号（open_id）,公众帐号, 消息类型,事件类型
			Map<String, String> requestMap = ParseXmlUtil.parseXml(request);
			log.info("获取请求参数:{}", requestMap);
			// 消息类型
			String msgType = requestMap.get("MsgType");
			log.info("获取用户消息,消息类型是:{}", msgType);
			// 事件推送
			if (msgType.equals(MsgTypes.EVENT.getType())) {
				// 事件类型
				String eventType = requestMap.get("Event");
				// 订阅
				if (eventType.equals(MsgTypes.EVENT_TYPE_SUBSCRIBE.getType())) {
					log.info("新用户关注了您的公众号,openId是:{}", requestMap.get("FromUserName"));
					// 获得关注回复内容
					return replyString(requestMap, getMainMenu());
				}
				// 取消订阅
				else if (eventType.equals(MsgTypes.EVENT_TYPE_UNSUBSCRIBE.getType())) {
					// 取消订阅后用户再收不到公众号发送的消息，因此不需要回复消息
					log.info("有用户取消关注了您的公众号,openID是:{}", requestMap.get("FromUserName"));
					return null;
				}
				// 自定义菜单点击事件
				// content 开头的表示文本， news 开头的表示图文
				else if (eventType.equals(MsgTypes.EVENT_TYPE_CLICK.getType())) {
					String buttonType = requestMap.get("EventKey");
					log.info("用户点击了您的微信菜单, the open id is{}, Event key is {}",
							requestMap.get("FromUserName"), buttonType);
					if (buttonType.startsWith("online")) {
						// 返回商店列表						
						return replyArticle(requestMap, getArticleList(), request);
					}
//					if (buttonType.startsWith("news")) {
//						// 回复自定义图文
//						return "";
//					}
//					else if (buttonType.startsWith("text")) {
//						// 回复自定义文本
//						return "";
//					}
				}
				// 点击view按钮事件
				else if (eventType.equals(MsgTypes.EVENT_TYPE_VIEW.getType())) {
					log.info("用户点击view按钮事件,the open id is{}", requestMap.get("FromUserName"));
					return null;
				}
				// 地理位置事件
				else if (eventType.equals(MsgTypes.LOCATION.getType())) {
					log.info("用户获取地理位置事件,the open id is{}", requestMap.get("FromUserName"));
					return "";
				}
				// 二维码事件
				else if (eventType.equals(MsgTypes.EVENT_TYPE_SCAN.getType())) {
					log.info("用户二维码扫描事件,the open id is{}", requestMap.get("FromUserName"));
					return "";
				}
			}
			else {
				// 如果不是event,就是消息
				log.info("用户给公众号发送了消息,the open id is{}", requestMap.get("FromUserName"));
				// 文本消息
				if (msgType.equals(MsgTypes.TEXT.getType())) {
					return autoReply(requestMap, request);
				}
				// 图片消息
				else if (msgType.equals(MsgTypes.IMAGE.getType())) {
					return autoReply(requestMap, request);
				}
				// 地理位置消息
				else if (msgType.equals(MsgTypes.LOCATION.getType())) {
					return autoReply(requestMap, request);
				}
				// 链接消息
				else if (msgType.equals(MsgTypes.LINK.getType())) {
					return autoReply(requestMap, request);
				}
				// 音频消息
				else if (msgType.equals(MsgTypes.VOICE.getType())) {
					return autoReply(requestMap, request);
				}
				// 视频消息
				else if (msgType.equals(MsgTypes.VIDEO.getType())) {
					return autoReply(requestMap, request);
				}
				// 客服服务
				else if (msgType.equals(MsgTypes.RESP_MESSAGE_TYPE_TRANSFER_CUSTOMER_SERVICE.getType())) {
					// 如果关闭了自动回复，就全部当做客服消息处理
					return replyCustomerService(requestMap);
				}
			}
			return replyString(requestMap, "请求处理异常，请稍候尝试！");
		} catch (Exception e) {
			log.error("unkown xml format", e);
		}
		return null;
	}

	/**
	 * 自动回复
	 * 
	 * @param requestMap
	 * @return
	 */
	private String autoReply(Map<String, String> requestMap, HttpServletRequest request) {
		String respMessage = "";
		String content = requestMap.get("Content"); // 内容
		List<WxAutoreply> wxAutoreplys = wxAutoreplyService.findByName(content, basePath);
		if (wxAutoreplys.size() == 0) {
			// 默认自动回复
			respMessage = replyString(requestMap, "默认消息");
		}
		else {
			// 回复图文消息
			respMessage = replyArticle(requestMap, wxAutoreplys, request);
		}
		log.info("autoReply {} with {}", content, wxAutoreplys);
		return respMessage;
	}

	/**
	 * 文本回复
	 * 
	 * @param requestMap
	 * @param respContent
	 * @return
	 */
	private String replyString(Map<String, String> requestMap, String respContent) {
		String respMessage = "";
		// 发送方帐号（open_id）
		String fromUserName = requestMap.get("FromUserName");
		// 公众帐号
		String toUserName = requestMap.get("ToUserName");
		// 回复文本消息
		TextMessage textMessage = new TextMessage();
		textMessage.setToUserName(fromUserName);
		textMessage.setFromUserName(toUserName);
		textMessage.setCreateTime(new Date().getTime());
		textMessage.setMsgType(MsgTypes.TEXT.getType());
		textMessage.setContent(respContent);
		respMessage = ParseXmlUtil.messageToXml(textMessage);
		return respMessage;
	}

	/**
	 * 多客服消息回复
	 * 
	 * @param requestMap
	 * @return
	 */
	private String replyCustomerService(Map<String, String> requestMap) {
		log.debug("客服方法被调用+---------------");
		String respMessage = "";
		String fromUserName = requestMap.get("FromUserName");
		String toUserName = requestMap.get("ToUserName");
		// 给服务器发送MsgType为transfer_customer_service通知服务器把消息转到多客服系统
		BaseMessage baseMessage = new BaseMessage();
		baseMessage.setToUserName(fromUserName);
		baseMessage.setFromUserName(toUserName);
		baseMessage.setCreateTime(new Date().getTime());
		baseMessage.setMsgType(MsgTypes.RESP_MESSAGE_TYPE_TRANSFER_CUSTOMER_SERVICE.getType());
		respMessage = ParseXmlUtil.messageToXml(baseMessage);
		return respMessage;
	}

	/**
	 * 多图文回复
	 * 
	 * @param requestMap
	 * @param id
	 * @return
	 */
	private String replyArticle(Map<String, String> requestMap, List<WxAutoreply> wxAutoreplys,
			HttpServletRequest request) {
		// 发送方帐号（open_id）
		String fromUserName = requestMap.get("FromUserName");
		// 公众帐号
		String toUserName = requestMap.get("ToUserName");
		// 接口图文对象
		List<Article> list = new ArrayList<Article>();
		// 回复多图文消息
		for (WxAutoreply reply : wxAutoreplys) {
			Article articles = new Article();
			articles.setTitle(reply.getTitle());
			articles.setDescription(reply.getDescription());
			articles.setUrl(reply.getUrl());
			articles.setPicUrl(reply.getPicUrl());
			list.add(articles);
		}
		// 取得内容
		NewsMessage newsMessage = new NewsMessage();
		newsMessage.setToUserName(fromUserName);
		newsMessage.setFromUserName(toUserName);
		newsMessage.setCreateTime(new Date().getTime());
		newsMessage.setMsgType(MsgTypes.NEWS.getType());
		newsMessage.setArticles(list);
		newsMessage.setArticleCount(list.size());
		String respMessage = ParseXmlUtil.messageToXml(newsMessage);
		return respMessage;
	}

	/**
	 * 主菜单
	 * 
	 * @return
	 */
	public String getMainMenu() {
/*		StringBuffer buffer = new StringBuffer();
		buffer.append(
				"您好，欢迎访问云易客，请回复内容选择服务。")
				.append("\n\n");
		buffer.append("云易客  图文1").append("\n");
		buffer.append("旅游  图文2").append("\n");
		buffer.append("其他  统一回复").append("\n");
		buffer.append("回复“?”显示内容");
		return buffer.toString();*/
		
		StringBuffer buffer = new StringBuffer();
		buffer.append(
				"感谢关注轻多了，请回复内容选择服务。")
				.append("\n\n");
		buffer.append("1、店内请选“店内购买”").append("\n");
		buffer.append("2、在家请选“线上购物”").append("\n");
		buffer.append("3、看物流选“个人中心”").append("\n");
		buffer.append("<a href=\"http://wx.yunyike.com/yunyike_web/image/post.jpg\">>时尚的人会点进去<</a> ");
		return buffer.toString();
	}
	
	public List<WxAutoreply> getArticleList() {
		List<WxAutoreply> wxAutoreplys = new ArrayList<WxAutoreply>();
		WxAutoreply wxAutoreply0 = new WxAutoreply();
		//暂时先写死， 以后要从表里读
		wxAutoreply0.setTitle("线上购买稍后开启， 敬请期待！");
		wxAutoreply0.setDescription("线上购买稍后开启， 敬请期待！");
		wxAutoreply0.setPicUrl(basePath + "/image/logo.jpg");
		wxAutoreply0.setUrl("http://wx.yunyike.com/yunyike_web/image/post.jpg");
		WxAutoreply wxAutoreply1 = new WxAutoreply();
		wxAutoreply1.setTitle("Parashop 法国最大药妆品牌连锁");
		wxAutoreply1.setDescription("Parashop 法国最大药妆品牌连锁");
		wxAutoreply1.setPicUrl(basePath + "/image/parashop.jpg");
		wxAutoreply1.setUrl("http://wx.yunyike.com/yunyike_web/image/post.jpg");

		WxAutoreply wxAutoreply2 = new WxAutoreply();
		wxAutoreply2.setTitle("Boggi 意大利男装品牌连锁");
		wxAutoreply2.setDescription("Boggi 意大利男装品牌连锁");
		wxAutoreply2.setPicUrl(basePath + "/image/bogi.jpg");
		wxAutoreply2.setUrl("http://wx.yunyike.com/yunyike_web/image/post.jpg");
		
		WxAutoreply wxAutoreply3 = new WxAutoreply();
		wxAutoreply3.setTitle("la Rinascete 意大利最大百货商店");
		wxAutoreply3.setDescription("la Rinascete 意大利最大百货商店");
		wxAutoreply3.setPicUrl(basePath + "/image/fuxing.jpg");
		wxAutoreply3.setUrl("http://wx.yunyike.com/yunyike_web/image/post.jpg");
		
		WxAutoreply wxAutoreply4 = new WxAutoreply();
		wxAutoreply4.setTitle("A. Caraceni sarti 米兰最古老的手工西装");
		wxAutoreply4.setDescription("A. Caraceni sarti 米兰最古老的手工西装");
		wxAutoreply4.setPicUrl(basePath + "/image/suit.jpg");
		wxAutoreply4.setUrl("http://wx.yunyike.com/yunyike_web/image/post.jpg");

		wxAutoreplys.add(wxAutoreply0);
		wxAutoreplys.add(wxAutoreply1);
		wxAutoreplys.add(wxAutoreply2);
		wxAutoreplys.add(wxAutoreply3);
		wxAutoreplys.add(wxAutoreply4);
		
		return wxAutoreplys;
	}
}